// Copyright Epic Games, Inc. All Rights Reserved.

#include "LyraBrightnessEditor.h"

#include "CommonButtonBase.h"
#include "CommonRichTextBlock.h"
#include "Components/WidgetSwitcher.h"
#include "GameSettingValueScalar.h"
#include "Settings/LyraSettingsLocal.h"
#include "Widgets/Layout/SSafeZone.h"

#include UE_INLINE_GENERATED_CPP_BY_NAME(LyraBrightnessEditor)

struct FGeometry;

#define LOCTEXT_NAMESPACE "Lyra"

namespace BrightnessEditor
{
	const float JoystickDeadZone = 0.2f; // 摇杆死区
	const float SafeZoneChangeSpeed = 0.1f; // 安全区域改变速度
}

/**
 * 构造函数
 * @param Initializer 对象初始化器
 */
ULyraBrightnessEditor::ULyraBrightnessEditor(const FObjectInitializer& Initializer)
	: Super(Initializer)
{
	SetVisibility(ESlateVisibility::Visible); // 设置可见性为可见
	SetIsFocusable(true); // 设置为可聚焦
}

/**
 * 原生初始化函数
 */
void ULyraBrightnessEditor::NativeOnInitialized()
{
	Super::NativeOnInitialized(); // 调用父类初始化
	Switcher_SafeZoneMessage->SetActiveWidget(RichText_Default); // 设置活动控件为默认富文本
}

/**
 * 原生激活函数
 */
void ULyraBrightnessEditor::NativeOnActivated()
{
	Super::NativeOnActivated(); // 调用父类激活函数

	SSafeZone::SetGlobalSafeZoneScale(ULyraSettingsLocal::Get()->GetSafeZone()); // 设置全局安全区域比例
	
	Button_Done->OnClicked().AddUObject(this, &ThisClass::HandleDoneClicked); // 绑定完成按钮点击事件

	Button_Back->SetVisibility((bCanCancel)? ESlateVisibility::Visible : ESlateVisibility::Collapsed); // 根据是否可以取消设置返回按钮可见性
	if (bCanCancel) // 如果可以取消
	{
		Button_Back->OnClicked().AddUObject(this, &ThisClass::HandleBackClicked); // 绑定返回按钮点击事件
	}
}

/**
 * 为设置执行操作的实现
 * @param ActionTag 操作标签
 * @param InSetting 游戏设置
 * @return 是否成功执行
 */
bool ULyraBrightnessEditor::ExecuteActionForSetting_Implementation(FGameplayTag ActionTag, UGameSetting* InSetting)
{
	TArray<UGameSetting*> ChildSettings = InSetting ? InSetting->GetChildSettings() : TArray<UGameSetting*>(); // 获取子设置
	if (ChildSettings.Num() > 0 && ChildSettings[0]) // 如果有子设置且第一个有效
	{
		ValueSetting = Cast<UGameSettingValueScalar>(ChildSettings[0]); // 转换为标量值设置
	}

	return true; // 返回成功
}

/**
 * 原生模拟值改变处理
 * @param InGeometry 几何信息
 * @param InAnalogEvent 模拟输入事件
 * @return 回复处理
 */
FReply ULyraBrightnessEditor::NativeOnAnalogValueChanged(const FGeometry& InGeometry, const FAnalogInputEvent& InAnalogEvent)
{
	if (InAnalogEvent.GetKey() == EKeys::Gamepad_LeftY && FMath::Abs(InAnalogEvent.GetAnalogValue()) >= BrightnessEditor::JoystickDeadZone) // 如果是左摇杆Y轴且超过死区
	{
		const float SafeZoneMultiplier = FMath::Clamp(SSafeZone::GetGlobalSafeZoneScale().Get(1.0f) + InAnalogEvent.GetAnalogValue() * BrightnessEditor::SafeZoneChangeSpeed, 0.0f, 1.0f); // 计算安全区域乘数
		SSafeZone::SetGlobalSafeZoneScale(SafeZoneMultiplier >= 0 ? SafeZoneMultiplier : 0); // 设置全局安全区域比例
		
		return FReply::Handled(); // 返回已处理
	}
	return Super::NativeOnAnalogValueChanged(InGeometry, InAnalogEvent); // 调用父类处理
}

/**
 * 原生鼠标滚轮处理
 * @param InGeometry 几何信息
 * @param InMouseEvent 鼠标事件
 * @return 回复处理
 */
FReply ULyraBrightnessEditor::NativeOnMouseWheel(const FGeometry& InGeometry, const FPointerEvent& InMouseEvent)
{
	const float SafeZoneMultiplier = FMath::Clamp(SSafeZone::GetGlobalSafeZoneScale().Get(1.0f) + InMouseEvent.GetWheelDelta() * BrightnessEditor::SafeZoneChangeSpeed, 0.0f, 1.0f); // 计算安全区域乘数
	SSafeZone::SetGlobalSafeZoneScale(SafeZoneMultiplier >= 0 ? SafeZoneMultiplier : 0); // 设置全局安全区域比例

	return FReply::Handled(); // 返回已处理
}

/**
 * 处理输入模式改变
 * @param InInputType 输入类型
 */
void ULyraBrightnessEditor::HandleInputModeChanged(ECommonInputType InInputType)
{
	const FText KeyName = InInputType == ECommonInputType::Gamepad ? LOCTEXT("SafeZone_KeyToPress_Gamepad", "Left Stick") : LOCTEXT("SafeZone_KeyToPress_Mouse", "Mouse Wheel"); // 根据输入类型获取按键名称
	RichText_Default->SetText(FText::Format(LOCTEXT("BrightnessAdjustInstructions", "Use <text color=\"FFFFFFFF\" fontface=\"black\">{0}</> to adjust the brightness"), KeyName)); // 设置富文本显示亮度调整说明
}

/**
 * 处理返回按钮点击
 */
void ULyraBrightnessEditor::HandleBackClicked()
{
	DeactivateWidget(); // 停用控件
	SSafeZone::SetGlobalSafeZoneScale(ULyraSettingsLocal::Get()->GetSafeZone()); // 恢复原始安全区域比例
}

/**
 * 处理完成按钮点击
 */
void ULyraBrightnessEditor::HandleDoneClicked()
{
	if (ValueSetting.IsValid()) // 如果值设置有效
	{
		ValueSetting.Get()->SetValue(SSafeZone::GetGlobalSafeZoneScale().Get(1.0f)); // 设置值
	}
	else // 否则
	{
		ULyraSettingsLocal::Get()->SetSafeZone(SSafeZone::GetGlobalSafeZoneScale().Get(1.0f)); // 设置安全区域
	}
	OnSafeZoneSet.Broadcast(); // 广播安全区域设置事件
	DeactivateWidget(); // 停用控件
}

#undef LOCTEXT_NAMESPACE